package com.zhss.dfs.namenode.server.editlog;

import com.zhss.dfs.namenode.server.context.DfsEnv;
import com.zhss.dfs.namenode.server.context.Environment;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class DoubleBuffer {

    /**
     * 是专门用来承载线程写入edits log
     */
    EditLogBuffer currentBuffer = new EditLogBuffer();
    /**
     * 专门用来将数据同步到磁盘中去的一块缓冲
     */
    EditLogBuffer syncBuffer = new EditLogBuffer();

    private Environment env = DfsEnv.getInstance();
    private volatile long startTxid;
    //已经刷入磁盘中的txid;
    public static List<String> flushedTxids = new CopyOnWriteArrayList<>();

    /**
     * 交换两块缓冲区，为了同步内存数据到磁盘做准备
     */
    public void setReadyToSync() {
        EditLogBuffer tmp = currentBuffer;
        currentBuffer = syncBuffer;
        syncBuffer = tmp;
    }

    public boolean shouldSyncToDisk() {
        if (currentBuffer.size() >= env.getEditlogBufferLimit()) {
            System.out.println("需要同步" + currentBuffer.size());
            return true;
        }
        return false;
    }

    /**
     * 获取sync buffer缓冲区里的最大的一个txid
     *
     * @return
     */


    /**
     * 将syncBuffer缓冲区中的数据刷入磁盘中
     */
    public void flush() throws IOException {
        startTxid = syncBuffer.flush(startTxid);
        syncBuffer.clear();
    }

    public void write(EditLog editLog) throws IOException {
        currentBuffer.write(editLog);
    }

    public List<String> getFlushedTxids() {
        return this.flushedTxids;
    }

    public String[] getBufferEditsLog() {
        if (currentBuffer.size() == 0) {
            return null;
        }
        String editsLogRawData = new String(currentBuffer.getBufferData());
        return editsLogRawData.split("\n");
    }
}
